home *** CD-ROM | disk | FTP | other *** search
/ The 640 MEG Shareware Studio 4 / The 640 Meg Shareware Studio CD-ROM Volume IV (Data Express)(1994).ISO / clang / 104_01.zip / C2.C < prev    next >
Text File  |  1993-06-14  |  13KB  |  511 lines

  1.  
  2.  
  3. #ifndef TRUE    /* see if need include file */
  4. #include <c.def>
  5. #endif
  6.  
  7. /*                    */
  8. /*    Get required array size        */
  9. /*                    */
  10. /* invoked when declared variable is follwed by "[" */
  11. /*      this routine makes subscript the absolute */
  12. /*      size of the array. */
  13. needsub()
  14. {
  15.     int num[1];
  16.     if (match("]")) return 0;    /* null size */
  17.     if (number(num)==0) {        /* go after a number */
  18.         error("must be constant");     /* it isn't */
  19.         while(ch() != ',' && ch() != ';' && ch()) gch();
  20.         return 1; 
  21.         }
  22.     if (num[0]<0) {
  23.         error("negative size illegal");
  24.         num[0]=(-num[0]);
  25.         }
  26.     needbrack("]");        /* force single dimension */
  27.     return num[0];        /* and return size */
  28.     }
  29. /*                */
  30. /*      Begin a function    */
  31. /*                */
  32. /* Called from "parse" this routine tries to make a function */
  33. /*      out of what follows.    */
  34. newfunc()
  35. {
  36.     char n[namesize],*ptr;
  37.     if (symname(n) == 0) {
  38.         error("illegal function or declaration");
  39.         kill();
  40.         return;
  41.         }
  42.     if (!match("(")) {
  43.         error("illegal function or declaration");
  44.         kill();
  45.         return;
  46.         }
  47.     if(ptr=findglb(n)) {      /* already in symbol table ? */
  48.         if (ptr[ident] != function) multidef(n);
  49.             /* already variable by that name */
  50.         else if(ptr[offset] == function) multidef(n);
  51.             /* already function by that name */
  52.         else {
  53.             ptr[offset]=function;
  54.             csect(n);
  55.             }
  56.             /* otherwise we have what was earlier*/
  57.             /*  assumed to be a function */
  58.         }
  59.     /* if not in table, define as a function now */
  60.     else {
  61.         /* fill in gobal symbol table */
  62.         if (glbptr>=endglb) 
  63.             error("gobal symbol table overflow");
  64.         else {
  65.             ptr=glbptr;
  66.             glbptr+=symsiz;
  67.             strcpy(ptr+name,n);
  68.             ptr[ident]=function;
  69.         ]=cint;
  70.             ptr[offset]=function;
  71.             ptr[offset1]=
  72.             ptr[indcnt]=
  73.             ptr[storage]=0;
  74.             }
  75.         csect(n);
  76.         }
  77.  
  78.     argstk=0;           /* init arg count */
  79.     while(match(")") == 0) {    /* then count args */
  80.         /* any legal name bumps arg count */
  81.         if (symname(n)) argstk=argstk+2;
  82.         else{
  83.             error("illegal argument name");
  84.             junk();
  85.             }
  86.         blanks();
  87.         /* if not closing paren, should be a comma */
  88.         if( streq(line+lptr,")") == 0) {
  89.             if(match(",")==0)
  90.             error("expected comma");
  91.             }
  92.         if(endst())break;
  93.         }
  94.     locptr=startloc;    /* "clear" local symbol table*/
  95.     sp=0;           /* preset stack ptr */
  96.     while(argstk) {
  97.         /* now let user declare what types of things */
  98.         /*      those arguments were */
  99.         if (amatch("char",4)) {
  100.             getarg(cchar);
  101.             ns();
  102.             }
  103.         else if (amatch("int",3)) {
  104.             getarg(cint);
  105.             ns();
  106.             }
  107.         else {
  108.             error("wrong number args");
  109.             break;
  110.             }
  111.         }
  112.     if(statement()!=streturn)  {
  113.             /* do a statement, but if */
  114.             /* it's a return, skip */
  115.             /* cleaning up the stack */
  116.         modstk(0);
  117.         ret();
  118.         }
  119.     sp=0;
  120.     locptr=startloc;
  121.     dumplits();
  122.     litlab=getlabel();
  123.     }
  124. /*                      */
  125. /*      Declare argument types      */
  126. /*                      */
  127. /* called from "newfunc" this routine adds a entry in the */
  128. /*      local symbol table for each named argument */
  129. getarg(t)           /* t = cchar or cint */
  130. int t;
  131. {
  132.     char n[namesize],c;int j,count;
  133.     while(1) {
  134.         count=0;
  135.         if (argstk == 0) return;   /* no more args */
  136.         if (match("*")) {
  137.             j=pointer;
  138.             ++count;
  139.             while(ch()=='*') {
  140.                 ++count;
  141.                 gch();
  142.                 }
  143.             }
  144.         else j=variable;
  145.         if (symname(n) == 0) illname();
  146.         if (findloc(n)) multidef(n);
  147.         data_parse(n,t,stkarg,j,count);
  148.         if(endst())return;
  149.         if(match(",")==0)error("expected comma");
  150.         }
  151.     }
  152. /*                      */
  153. /*      Statement parser        */
  154. /*                      */
  155. /* called whenever syntax requires      */
  156. /*      a statement.             */
  157. /*  this routine performs that statement */
  158. /*  and returns a number telling which one */
  159. statement()
  160.  {      if (!ch() && eof) return;
  161.     else if(amatch("char",4)) {
  162.         declloc(cchar);
  163.         ns();
  164.         }
  165.     else if(amatch("int",3)) {
  166.         declloc(cint);
  167.         ns();
  168.         }
  169.     else if(match("{")) compound();
  170.     else if(amatch("if",2)) {
  171.         doif();
  172.         lastst=stif;
  173.         }
  174.     else if(amatch("while",5)) {
  175.         dowhile();
  176.         lastst=stwhile;    
  177.         }
  178.     else if (amatch("for",3)) {
  179.         dofor();
  180.         lastst=stfor;
  181.         }
  182.     else if (amatch("switch",6)) {
  183.         doswitch();
  184.         lastst=stswitch;
  185.         }
  186.     else if(amatch("return",6)) {
  187.         doreturn();
  188.         ns();
  189.         lastst=streturn;
  190.         }
  191.     else if(amatch("break",5)) {
  192.         dobreak();
  193.         ns();
  194.         lastst=stbreak;
  195.         }
  196.     else if(amatch("continue",8)) {
  197.         docont();
  198.         ns();
  199.         lastst=stcont;
  200.         }
  201.     else if(match(";"));
  202.     else if(match("#asm")) {
  203.         doasm();
  204.         ns();
  205.         lastst=stasm;
  206.         }
  207.     /* if nothing else, assume it's an expression */
  208.     else {
  209.         expression();
  210.         ns();
  211.         lastst=stexp;
  212.         }
  213.     return lastst;
  214.     }
  215. /*                      */
  216. /*      Semicolon enforcer          */
  217. /*                      */
  218. /* called whenever syntax requires a semicolon */
  219. ns()    {if(match(";")==0)error("missing semicolon");}
  220. /*                    */
  221. /*    need semicolon            */
  222. /*    written    by Mike    Bernson    1/81    */
  223. /*                    */
  224. needsem()
  225. {
  226.     if (match(";"))    return FALSE;
  227.     error("Missing semicolon");
  228.     junk();
  229.     return TRUE;
  230.     }
  231. /*                    */
  232. /*    need opening parn        */
  233. /*    written    by Mike    Bernson    1/81    */
  234. needoparn()
  235. {
  236.     if (match("("))    return FALSE;
  237.     error("Missing left parnthis");
  238.     junk();
  239.     return TRUE;
  240.     }
  241. /*                    */
  242. /*    need closing parn        */
  243. /*    written    by Mike    Bernson    1/81    */
  244. needcparn()
  245. {
  246.     if (match(")"))    return FALSE;
  247.     error("Missing right parnthis");
  248.     junk();
  249.     return TRUE;
  250.     }
  251. /*                    */
  252. /*    need opening brace        */
  253. /*    written    by Mike    Bernson    1/81    */
  254. needobrace()
  255. {
  256.     if (match("{"))    return FALSE;
  257.     error("Missing left brace");
  258.     junk();
  259.     return TRUE;
  260.     }
  261. /*                    */
  262. /*    need closing brace        */
  263. /*    written    by Mike    Bernson    1/81    */
  264. needcbrace()
  265. {
  266.     if (match("}"))    return FALSE;
  267.     error("Missing right brace");
  268.     junk();
  269.     return TRUE;
  270.     }
  271. /*                      */
  272. /*      Compound statement          */
  273. /*                      */
  274. /* allow any number of statements to fall between "{}" */
  275. compound()
  276.     {
  277.     ++ncmp;     /* new level open */
  278.     while(match("}")==0)
  279.         if(eof) return;
  280.         else statement();
  281.     --ncmp;     /* close current level */
  282.     }
  283. /*                      */
  284. /*          "if" statement      */
  285. /*                      */
  286. doif()
  287.     {
  288.     int flev,fsp,flab1,flab2;
  289.     flev=locptr;    /* record current local level */
  290.     fsp=sp;     /* record current stk ptr */
  291.     flab1= getlabel(); /* get label for false branch */
  292.     test(flab1);    /*get expression, and branch false */
  293.     statement();    /* if true, do a statement */
  294.     sp=modstk(fsp); /* then clean up the stack */
  295.     locptr=flev;    /* and deallocate any locals */
  296.     if (amatch("else",4)==0)    /* if...else ? */
  297.         /* simple "if"...print false label */
  298.         {sprintlabel(flab1);
  299.         return; /* and exit */
  300.         }
  301.     /* an "if...else" statement. */
  302.     jump(flab2=getlabel()); /* jump around the false code */
  303.     sprintlabel(flab1);    /* print true label */
  304.     statement();        /* and do else clause */
  305.     sp=modstk(fsp);        /* then clean up stack ptr */
  306.     locptr=flev;        /* dellocate locals */
  307.     sprintlabel(flab2);    /* print true label */
  308.     }
  309. /*                      */
  310. /*      "while" statement           */
  311. /*                      */
  312. dowhile()
  313.     {
  314.     int que[wqsiz];                /* allocate local queue */
  315.  
  316.     que[wqsym]=locptr;          /* record local level */
  317.     que[wqsp]=sp;               /* and stk ptr */
  318.     que[wqloop]=            /* and looping label */
  319.     que[wqend]=getlabel();        /* continue label */
  320.     que[wqlab]=getlabel();        /* and exit label */
  321.     addwhile(que);            /* add to looping stack    */
  322.     sprintlabel(que[wqloop]);    /* loop label */
  323.     test(que[wqlab]);        /* see if true */
  324.     statement();            /* if so, do a statement */
  325.     jump(que[wqloop]);        /* loop    to label */
  326.     sprintlabel(que[wqlab]);    /* exit label */
  327.     locptr=que[wqsym];        /* deallocate locals */
  328.     sp=modstk(que[wqsp]);        /* clean up stk    ptr */
  329.     delwhile();            /* delete queue    entry */
  330.     }
  331. /*                    */
  332. /*    "Switch" statement        */
  333. /*                    */
  334. /*    written by Mike Bernson 1/81    */
  335. /*                    */
  336. doswitch()
  337. {
  338.     int value[SWITCH_MAX];  /* value for case statemant */
  339.     int label[SWITCH_MAX];  /* value for each label */
  340.     int count,tenp;     /* number of switches */
  341.     int end_label;      /* label for default */
  342.     int label_switch;    /* used for switch label */
  343.     int temp,val[2];
  344.     int que[wqsiz];        /* local que area */
  345.     count=0;        /* number of case statements */
  346.     que[wqsym]=locptr;    /* local vable pointer */
  347.     que[wqsp]=sp;        /* save current stack pointer */
  348.     end_label=        /* default exit label */
  349.     que[wqloop]=        /* looping label */
  350.     que[wqlab]=        /* loop exit varble */
  351.     que[wqend]=getlabel();    /* continue label */
  352.     addwhile(que);        /* add to while stack */
  353.     if (needoparn()) {    /* check to see    if"(" exits */
  354.         delwhile();    /* no delete switch entry and */
  355.         return;        /* return out of switch    */
  356.         }
  357.     expression();        /* expression for switch */
  358.     push();
  359.     if (needcparn()) {    /* check for ")" */
  360.         delwhile();    /* not fould detele que    entry */
  361.         return;        /* and exit switch statemant */
  362.         }
  363.     if (needobrace()) {
  364.         delwhile();
  365.         return;
  366.         }
  367.     jump(label_switch=getlabel());
  368.     sp=sp+2;
  369.  
  370.     while(1) {
  371.      if (amatch("case",4)) {
  372.             if (const_exp(val) == 0 ) {
  373.                 error("Bad constant");
  374.                 continue;
  375.                 }
  376.             if (count<SWITCH_MAX-2) {
  377.                 value[count]=val[0];
  378.                 sprintlabel(label[count++]=getlabel());
  379.                 }
  380.             else error("Too many case statments");
  381.             if (!match(":")) error("Missing colon");
  382.             }
  383.     else if (amatch("default",7)) {
  384.         end_label=getlabel();
  385.         sprintlabel(end_label);
  386.         if (!match(":")) error("Missing colon");
  387.         }
  388.     else if (match("}")) {
  389.         jump(que[wqlab]);    /* jump past switch data */
  390.         temp=0;
  391.         sprintlabel(label_switch);
  392.         exec_switch(count,label_switch=getlabel(),end_label);
  393.         sprintlabel(label_switch);
  394.         while(temp<count) {
  395.             defword();
  396.             outdec(value[temp]);
  397.             outstr(",");
  398.             printlabel(label[temp++]);
  399.             nl();
  400.             }
  401.         delwhile();
  402.         sprintlabel(que[wqlab]);
  403.         locptr=que[wqsym];
  404.         sp=modstk(que[wqsp]);
  405.         return;
  406.         }
  407.     else statement();
  408.     }}
  409. /*                    */
  410. /*    "for" statement            */
  411. /*                    */
  412. /*    written by Mike Bernson 1/81    */
  413. /*                    */
  414. dofor()
  415. {
  416.     int que[wqsiz];        /* local que area */
  417.     int status;        /* machine status after expession */
  418.  
  419.     que[wqsym]=locptr;    /* save locaL LEVEL */
  420.     que[wqsp]=sp;        /* and stack pointer */
  421.     que[wqloop]=getlabel();    /* looping label */
  422.     que[wqlab]=getlabel();    /* loop exit varble */
  423.     que[wqend]=getlabel();    /* loop end label */
  424.     que[wqbody]=getlabel();    /* body for cody */
  425.     addwhile(que);        /* add while to loop que */
  426.     if (needoparn()) {    /* check for open parn */
  427.         delwhile();    /* delete for entry from que */
  428.         return;
  429.         }
  430.     expression();        /* init    express    */
  431.     if (needsem()) {    /* check for semcol */
  432.         delwhile();    /* delete que entry */
  433.         return;
  434.         }
  435.     sprintlabel(que[wqloop]);    /* control loop    label */
  436.     status=expression();        /* loop control express */
  437.     testjump(que[wqlab],status);    /* see if exit time */
  438.     jump(que[wqbody]);    /* not time to exit do body */
  439.     if (needsem()) {    /* check for semcol */
  440.         delwhile();    /* delete 1 que    entry */
  441.         return;
  442.         }
  443.     sprintlabel(que[wqend]);    /* print end of loop */
  444.     expression();        /* end loop expression */
  445.     jump(que[wqloop]);    /* do loop control expression */
  446.     if (needcparn()) {
  447.         delwhile();
  448.         return;
  449.         }
  450.     sprintlabel(que[wqbody]);
  451.     statement();
  452.     jump(que[wqend]);
  453.     sprintlabel(que[wqlab]);
  454.     locptr=que[wqsym];
  455.     sp=modstk(que[wqsp]);
  456.     delwhile();
  457.     }
  458. /*                       */
  459. /*      "return" statement          */
  460. /*                      */
  461. doreturn()
  462.     {
  463.     /* if not end of statement, get an expression */
  464.     if(endst()==0)expression();
  465.     modstk(0);      /* clean up stk */
  466.     ret();      /* and exit function */
  467.     }
  468. /*                      */
  469. /*      "break" statement           */
  470. /*                      */
  471. dobreak()
  472.     {
  473.     int *ptr;
  474.     /* see if any "whiles" are open */
  475.     if ((ptr=readwhile())==0) return;       /* no */
  476.     modstk(ptr[wqsp]);    /* else clean up stk ptr */
  477.     jump(ptr[wqlab]);       /* jump to exit label */
  478.     }
  479. /*                      */
  480. /*      "continue" statement        */
  481. /*                      */
  482. docont()
  483.     {
  484.     int *ptr;
  485.     /* see if any "whiles" are open */
  486.     if ((ptr=readwhile())==0) return;       /* no */
  487.     modstk((ptr[wqsp]));    /* else clean up stk ptr */
  488.     jump(ptr[wqend]);      /* jump to end label */
  489.     }
  490. /*                      */
  491. /*      "asm" pseudo-statement      */
  492. /*                      */
  493. /* enters mode where assembly language statements are */
  494. /*      passed intact through parser    */
  495. doasm()
  496.     {
  497.     cmode=0;    /* mark mode as "asm" */
  498.     while(1)
  499.         {inline();      /* get and print lines */
  500.         if (match("#endasm")) break;    /* until... */
  501.         if(eof)break;
  502.         outstr(line);
  503.         nl();
  504.         }
  505.     kill();     /* invalidate line */
  506.     cmode=1;
  507.     }
  508.  
  509.  
  510.  
  511.